﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace NORM.Common
{
    public static class EncryptDES
    {
        //默认密钥向量 

        private static byte[] Keys = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };

        private static string KEY = "@k#%s!$97#";
        /// <summary> 
        /// DES加密字符串 
        /// </summary> 
        /// <param name="encryptString">待加密的字符串</param> 
        /// <returns>加密成功返回加密后的字符串，失败返回源串</returns> 
        public static string EncryptDESM(string encryptString)
        {
            try
            {
                using (MemoryStream mStream = new MemoryStream())
                {
                    byte[] rgbKey = Encoding.UTF8.GetBytes(KEY.Substring(0, 8));
                    byte[] rgbIV = Keys;
                    byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
                    DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();
                    CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
                    cStream.Write(inputByteArray, 0, inputByteArray.Length);
                    cStream.FlushFinalBlock();
                    return Convert.ToBase64String(mStream.ToArray());
                }                
            }
            catch (Exception ex)
            {
                return encryptString;
            }

        }
        
        /// <summary>
        /// DES加密字符串 
        /// </summary>
        /// <param name="PubKey">加密密钥,要求为8位</param>
        /// <param name="encryptString">加密字符串</param>
        /// <returns>加密成功返回加密后的字符串，失败返回源串</returns>
        public static string EncryptDESM(string PubKey, string encryptString)
        {
            try
            {
                using (MemoryStream mStream = new MemoryStream())
                {
                    byte[] rgbKey = Encoding.UTF8.GetBytes(PubKey.Substring(0, 8));
                    byte[] rgbIV = Keys;
                    byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
                    DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();
                    CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
                    cStream.Write(inputByteArray, 0, inputByteArray.Length);
                    cStream.FlushFinalBlock();
                    return Convert.ToBase64String(mStream.ToArray());
                }                
            }
            catch
            {
                return encryptString;
            }

        }
        
        /// <summary> 
        /// DES解密字符串 
        /// </summary> 
        /// <param name="decryptString">待解密的字符串</param> 
        /// <returns>解密成功返回解密后的字符串，失败返源串</returns> 
        public static string DecryptDES(string decryptString)
        {
            try
            {
                using (MemoryStream mStream = new MemoryStream())
                {
                    byte[] rgbKey = Encoding.UTF8.GetBytes(KEY.Substring(0, 8));
                    byte[] rgbIV = Keys;
                    byte[] inputByteArray = Convert.FromBase64String(decryptString);
                    DESCryptoServiceProvider DCSP = new DESCryptoServiceProvider();
                    CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
                    cStream.Write(inputByteArray, 0, inputByteArray.Length);
                    cStream.FlushFinalBlock();
                    return Encoding.UTF8.GetString(mStream.ToArray());
                }                
            }
            catch (Exception ex)
            {
                return decryptString;
            }

        }

        /// <summary>
        /// DES解密字符串
        /// </summary>
        /// <param name="PubKey">解密密钥,要求为8位,和加密密钥相同</param>
        /// <param name="decryptString">待解密的字符串</param>
        /// <returns>解密成功返回解密后的字符串，失败返源串</returns>
        public static string DecryptDES(string PubKey, string decryptString)
        {
            try
            {
                using (MemoryStream mStream = new MemoryStream())
                {
                    byte[] rgbKey = Encoding.UTF8.GetBytes(PubKey.Substring(0, 8));
                    byte[] rgbIV = Keys;
                    byte[] inputByteArray = Convert.FromBase64String(decryptString);
                    DESCryptoServiceProvider DCSP = new DESCryptoServiceProvider();
                    CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
                    cStream.Write(inputByteArray, 0, inputByteArray.Length);
                    cStream.FlushFinalBlock();
                    return Encoding.UTF8.GetString(mStream.ToArray());
               }
            }
            catch
            {
                return decryptString;
            }

        }
    }

    /// <summary>
    /// 
    /// </summary>
    public static class DEncrypt
    {
        /// <summary>
        /// 对称加密
        /// </summary>
        /// <param name="input">输入字符串</param>
        /// <param name="key">密钥</param>
        /// <returns></returns>
        public static string Encrypt(string input, string key)
        {
            string rvl = input;

            try
            {
                byte[] key_array = System.Text.Encoding.UTF8.GetBytes(key);
                byte[] input_array = System.Text.Encoding.UTF8.GetBytes(input);

                using (TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider())
                {
                    using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider())
                    {
                        byte[] keyhash = md5.ComputeHash(key_array);
                        des.Key = keyhash;
                        des.Mode = CipherMode.ECB; //CipherMode.ECB;
                        ICryptoTransform transf = des.CreateEncryptor();
                        byte[] temp_array = transf.TransformFinalBlock(input_array, 0, input_array.Length);

                        StringBuilder rel_str = new StringBuilder();

                        for (int i = 0; i < temp_array.Length; i++)
                        {
                            int val = ((int)temp_array[i]) & 0xff;
                            if (val < 16)
                            {
                                rel_str.Append("0" + val.ToString("X"));
                            }
                            else
                            {
                                rel_str.Append(val.ToString("X"));
                            }

                        }

                        transf.Dispose();
                        rvl = rel_str.ToString();

                    }
                }
            }
            catch (Exception ex)
            {

            }

            return rvl;
        }
        
        /// <summary>
        /// 对称解密
        /// </summary>
        /// <param name="input">输入字符串</param>
        /// <param name="key">密钥</param>
        /// <returns></returns>
        public static string Decrypt(string input, string key)
        {
            string rvl = input;

            try
            {
                byte[] key_array = System.Text.Encoding.UTF8.GetBytes(key);
                char[] input_char = input.ToCharArray(); //System.Text.Encoding.Default.GetBytes(input);

                byte[] input_array = new byte[input_char.Length / 2];

                int i = 0;
                while (i < input_char.Length)
                {
                    string s = new String(new char[]{ 
                        input_char[i],
                        input_char[i + 1] });                     
                    byte a = (byte)Convert.ToInt32(s, 16);
                    input_array[i / 2] = a;
                    i = i + 2;
                }

                using (TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider())
                {
                    using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider())
                    {
                        byte[] keyhash = md5.ComputeHash(key_array);
                        des.Key = keyhash;
                        des.Mode = CipherMode.ECB; //CipherMode.ECB;
                        ICryptoTransform transf = des.CreateDecryptor();
                        byte[] temp_array = transf.TransformFinalBlock(input_array, 0, input_array.Length);

                        transf.Dispose();
                        rvl = System.Text.Encoding.UTF8.GetString(temp_array);

                    }
                }
            }
            catch (Exception ex)
            {

            }

            return rvl;
        }

    }
}
